﻿/*global Ext, document, jsonviewer */
String.prototype.trim = function () {
	return this.replace(/(^\s*)|(\s*$)/g, "");
}
/*
 * TODO:
 * keresés eltüntetéséhez gomb
 * keresésnél írjuk ki, hogy hány találat van (akár dinamikusan, hogy pörögjön felfelé)
 * about JSON Viewer ablak
 * "Format..." finomítása
 * Editable Grid
 * Griden dupla katt egy object-en, akkor válassza ki azt.
 * be lehessen állítani, hogy a kis és nagybetű számít-e?
 * tree.contextmenu (kinyít, becsuk, ?)
 *
 */

Ext.override(Ext.tree.TreeNode, {
	removeAllChildren: function () {
		while (this.hasChildNodes()) {
			this.removeChild(this.firstChild);
		}
		return this;
	},
	setIcon: function (icon) {
		this.getUI().setIcon(icon);
	},
	setIconCls: function (icon) {
		this.getUI().setIconCls(icon);
	}
});

Ext.override(Ext.tree.TreeNodeUI, {
	setIconCls: function (iconCls) {
		if (this.iconNode) {
			Ext.fly(this.iconNode).replaceClass(this.node.attributes.iconCls, iconCls);
		}
		this.node.attributes.iconCls = iconCls;
	},
	setIcon: function (icon) {
		if (this.iconNode) {
			this.iconNode.src = icon || this.emptyIcon;
			Ext.fly(this.iconNode)[icon ? 'addClass' : 'removeClass']('x-tree-node-inline-icon');
		}
		this.node.attributes.icon = icon;
	}
});

Ext.override(Ext.Panel, {
	hideBbar: function () {
		if (!this.bbar) {
			return;
		}
		this.bbar.setVisibilityMode(Ext.Element.DISPLAY);
		this.bbar.hide();
		this.getBottomToolbar().hide();
		this.syncSize();
		if (this.ownerCt) {
			this.ownerCt.doLayout();
		}
	},
	showBbar: function () {
		if (!this.bbar) {
			return;
		}
		this.bbar.setVisibilityMode(Ext.Element.DISPLAY);
		this.bbar.show();
		this.getBottomToolbar().show();
		this.syncSize();
		if (this.ownerCt) {
			this.ownerCt.doLayout();
		}
	}
});

Ext.ux.iconCls = function () {
	var styleSheetId = 'styleSheetIconCls';
	var cssClasses = {};
	Ext.util.CSS.createStyleSheet('/* Ext.ux.iconCls */', styleSheetId);
	return {
		get: function (icon) {
			if (!icon) {
				return null;
			}
			if (typeof cssClasses[icon] === 'undefined') {
				cssClasses[icon] = 'icon_' + Ext.id();
				var styleBody = '\n.' + cssClasses[icon] + ' { background-image: url(' + icon + ') !important; }';
				if (Ext.isIE) {
					document.styleSheets[styleSheetId].cssText += styleBody;
				} else {
					Ext.get(styleSheetId).dom.sheet.insertRule(styleBody, 0);
				}
			}
			return cssClasses[icon];
		}
	};
}();

String.space = function (len) {
	var t = [], i;
	for (i = 0; i < len; i++) {
		t.push(' ');
	}
	return t.join('');
};

function aboutWindow() {
	var tabs = [];
	Ext.getBody().select('div.tab').each(function (div) {
		tabs.push({
			title: div.select('h2').first().dom.innerHTML,
			html: div.select('div').first().dom.innerHTML.replace('{gabor}', '如果觉得好用,请按Ctrl+D收藏！谢谢！')
		});
	});
	var win = new Ext.Window({
		title: document.title,
		width: 640,
		height: 400,
		modal: true,
		layout: 'fit',
		items: new Ext.TabPanel({
			defaults: {
				autoScroll: true,
				bodyStyle: 'padding: 5px;'
			},
			activeTab: 0,
			items: tabs
		})
	});
	win.show();
}

function getSelectedItems(node) {
	//var childnodes = node.childNodes||node.attributes.children;
	var childnodes = node.attributes.children;
	for (var i = 0; i < childnodes.length; i++) {  //从节点中取出子节点依次遍历
		var rootnode = childnodes[i];
		alert(rootnode.text);
		if (rootnode.attributes.children.length > 0) {  //判断子节点下是否存在子节点，个人觉得判断是否leaf不太合理，因为有时候不是leaf的节点也可能没有子节点
			findchildnode(rootnode);    //如果存在子节点  递归
		}
	}
}
var copyTimer;
Ext.onReady(function () {

	Ext.BLANK_IMAGE_URL = '//static.json.cn/r/tpl/json/jsonview/jsonview/ico1/s.gif';
	Ext.QuickTips.init();

	var ctrlF = new Ext.KeyMap(document, [{
		key: Ext.EventObject.F,
		ctrl: true,
		stopEvent: true,
		fn: function () {
			jsonviewer.ctrlF();
		}
	}, {
		key: Ext.EventObject.H,
		ctrl: true,
		stopEvent: true,
		fn: function () {
			jsonviewer.hideToolbar();
		}
	}]);
	ctrlF.disable();

	var grid = {
		xtype: 'propertygrid',
		id: 'grid',
		title: '属性',
		region: 'east',
		width: 300,
		split: true,
		listeners: {
			beforeedit: function () {
				return false;
			}
		},
		selModel: new Ext.grid.RowSelectionModel(),
		onRender: Ext.grid.PropertyGrid.superclass.onRender
	};
	var tree = {
		id: 'tree',
		xtype: 'treepanel',
		region: 'center',
		title: '视图',
		loader: new Ext.tree.TreeLoader(),
		lines: true,
		root: new Ext.tree.TreeNode({ text: 'JSON' }),
		autoScroll: true,
		trackMouseOver: false,
		//	footer: new Ext.Panel({id:'www',region: 'south',height:90}),
		listeners: {
			render: function (tree) {
				tree.getSelectionModel().on('selectionchange', function (tree, node) {
					jsonviewer.gridbuild(node);
				});

				tree.on('contextmenu', function (node, e) {
					//var selectNode = tree.getSelectionModel().getLastSelected();
					//	alert(selectNode.data);
					var menu = new Ext.menu.Menu({
						minWidth: 120,
						items: [
							{
								text: '复制Key',
								iconCls: 'newdep_images',  //样式
								id: "copyItem",
								handler: function () {
									var _key = node.text.split(":")[0] + "";
									// window.prompt("请复制",_key.trim());
									//复制
									new ClipboardJS('#copyTxt', {
										text: function (trigger) {
											return _key.trim();
										}
									});
									document.getElementById('copyTxt').click();
									clearTimeout(copyTimer);
									document.getElementById('copySuccess').style.display = 'block';
									document.getElementById('copySuccess').innerText = 'Key 复制成功';
									copyTimer = setTimeout(function () {
										document.getElementById('copySuccess').style.display = 'none';
									}, 2000)
								}
							},
							{
								text: '复制Value',
								iconCls: 'newdep_images',  //样式
								handler: function () {
									var _value = node.text;
									_value = _value.substring(_value.indexOf(":") + 1);
									_value = _value.replace(/"/g, '');
									// window.prompt("请复制",_value.trim());
									//复制
									new ClipboardJS('#copyTxt', {
										text: function (trigger) {
											return _value.trim();
										}
									});
									clearTimeout(copyTimer);
									document.getElementById('copyTxt').click();
									document.getElementById('copySuccess').style.display = 'block';
									document.getElementById('copySuccess').innerText = 'Value 复制成功';
									copyTimer = setTimeout(function () {
										document.getElementById('copySuccess').style.display = 'none';
									}, 2000)
								}
							},
							{
								text: '复制Key+Value',
								iconCls: 'newdep_images',  //样式
								handler: function () {
									// window.prompt("请复制",node.text);
									//复制
									new ClipboardJS('#copyTxt', {
										text: function (trigger) {
											return node.text;
										}
									});
									clearTimeout(copyTimer);
									document.getElementById('copyTxt').click();
									document.getElementById('copySuccess').style.display = 'block';
									document.getElementById('copySuccess').innerText = 'Key+Value 复制成功';
									copyTimer = setTimeout(function () {
										document.getElementById('copySuccess').style.display = 'none';
									}, 2000)
								}
							}, {
								text: '展开所有子节点',
								iconCls: 'newdep_images',  //样式
								id: "exp_Item",
								handler: function () {
									node.expand(true);
									/*node.eachChild(function(child) {
									child.expand();
									});*/
								}
							},
							{
								text: '展开所有节点',
								iconCls: 'newdep_images',  //样式
								id: "exp_All",
								handler: function () {
									tree.getRootNode().expand(true);
								}
							},
							{
								text: '收起所有子节点',
								iconCls: 'newdep_images',  //样式
								id: "hide_Item",
								handler: function () {
									node.collapse(true);
									/*node.eachChild(function(child) {
									child.expand();
									});*/
								}
							},
							{
								text: '收起所有节点',
								iconCls: 'newdep_images',  //样式
								id: "hide_All",
								handler: function () {
									tree.getRootNode().collapse(true);
								}
							}
						]
					})
					menu.showAt(e.getPoint());
					var x = '';
				});
			}
		},
		tbar: [
			'查找:',
			new Ext.form.TextField({
				xtype: 'textfield',
				id: 'searchTextField'
			}),
			new Ext.Button({
				text: 'GO!',
				handler: function () {
					jsonviewer.searchStart();
				}
			}),
			new Ext.form.Label({
				id: 'searchResultLabel',
				style: 'padding-left:10px;font-weight:bold'
			}), {
				iconCls: Ext.ux.iconCls.get('//static.json.cn/r/tpl/json/jsonview/jsonview/ico1/arrow_down.png'),
				text: '下一个',
				handler: function () {
					jsonviewer.searchNext();
				}
			}, {
				iconCls: Ext.ux.iconCls.get('//static.json.cn/r/tpl/json/jsonview/jsonview/ico1/arrow_up.png'),
				text: '上一个',
				handler: function () {
					jsonviewer.searchPrevious();
				}
			},
			'-',
			{
				text: '全部展开', handler: function () {
					jsonviewer.expandAllTreeNode();
				}
			},
			{
				text: '全部收缩', handler: function () {
					jsonviewer.collapseAllTreeNode();
				}
			},
			'->',
			{
				text: '回到首页', handler: function () {
					window.location.href = "/";
				}
			}
			//,{ text: '关于', handler: aboutWindow }

		]
	};
	var edit = {
		id: 'edit',
		xtype: 'textarea',
		style: 'font-family:monospace',
		emptyText: '将JSON数据粘贴到这里!',
		selectOnFocus: true,
		listeners: {
			change: function () {
				console.log("edit-> change-->改变了");
				return jsonviewer.check();
			}
		}
	};
	var hoverStatus = -1;
	var textPanel = {
		id: 'textPanel',
		layout: 'fit',
		region: 'west',
		width: 400,
		split: true,
		title: 'JSON数据',
		tbar: [
			// {text: '粘贴', handler: function () {
			// 		jsonviewer.pasteText();
			// 	}},
			{
				text: '复制', handler: function () {
					jsonviewer.copyText();
				}
			},
			'-',
			{
				text: '格式化', handler: function () {
					jsonviewer.format();
				}
			},
			'-',
			{
				text: '删除空格', handler: function () {
					jsonviewer.removeWhiteSpace();
				}
			},
			'-',
			{
				text: '删除空格并转义', handler: function () {
					jsonviewer.removeWhiteSpace2();
				}
			},
			'-',
			{
				text: '去除转义', handler: function () {
					jsonviewer.removeZhuanyi();
				},
				listeners: {
					mouseover: function () {
						hoverStatus = 1;
					},
					mouseout: function () {
						hoverStatus = 0;
					}
				}
			}

		],
		items: edit
	};


	var vp = new Ext.Viewport({
		layout: 'border',
		items: [textPanel, {
			id: 'textwwPanel',
			region: 'center',
			layout: 'border',
			items: [tree, {
				// id: 'feee',
				// region:'south',
				// height:90,
				// contentEl : 'google-ad1'
			}
			]
			//contentEl : 'google-ad1',
			//split: true,
			//title: 'JSON数据',
		}, grid]
	});

	var jsonviewer = function () {
		var edit = Ext.getCmp('edit');
		var tree = Ext.getCmp('tree');
		var root = tree.getRootNode();
		var grid = Ext.getCmp('grid');
		var searchTextField = Ext.getCmp('searchTextField');
		var searchResultLabel = Ext.getCmp('searchResultLabel');
		var json = {};
		var lastText = null;
		var task = null;
		var searchList = null;
		var searchIndex = null;
		return {
			check: function () {
				if (hoverStatus === 1) {
					jsonviewer.removeZhuanyi();
				}
				// delete empty rows:
				var text = edit.getValue().split("\n").join(" ");
				try {
					// json = Ext.util.JSON.decode(text);
					var stringedJSON = text.replace(/([^\\]\"):\s*(\[)?([-+Ee0-9.]+)/g, '$1: $2"jsondotcnprefix$3"');
					json = JSON.parse(stringedJSON, function (key, value) {
						// only changing strings
						if (typeof value !== 'string') return value;
						// only changing number strings
						if (!value.startsWith('jsondotcnprefix')) return value;
						// chop off the prefix
						value = value.slice('jsondotcnprefix'.length);
						// pick your favorite arbitrary-precision library
						return new BigNumber(value);
					});

				} catch (e) {
					Ext.MessageBox.show({
						title: 'JSON 错误',
						msg: 'JSON 格式错误',
						icon: Ext.MessageBox.ERROR,
						buttons: Ext.MessageBox.OK,
						closable: false
					});
					return false;
				}
				if (lastText === text) {
					return;
				}
				lastText = text;
				this.treebuild();

				//格式化成功 进行session缓存 到temp_str
				sessionStorage.setItem('temp_str', lastText);
			},
			treebuild: function () {
				root.removeAllChildren();
				root.appendChild(this.json2leaf(json));
				root.setIcon(Ext.isArray(json) ? 'js/jsonview/ico1/array.gif' : 'js/jsonview/ico/object.gif');
				this.gridbuild(root);
			},
			gridbuild: function (node) {
				if (node.isLeaf()) {
					node = node.parentNode;
				}
				// elofordulhat, hogy nincsen még kifejtve:
				if (!node.childNodes.length) {
					node.expand(false, false);
					node.collapse(false, false);
				}
				var source = {};
				for (var i = 0; i < node.childNodes.length; i++) {
					var t = node.childNodes[i].text.split(':');
					if (t.length > 1) {
						source[t[0]] = t[1];
					} else {
						source[t[0]] = '...';
					}
				}
				grid.setSource(source);
			},
			json2leaf: function (json) {
				var ret = [];
				for (var i in json) {
					if (json.hasOwnProperty(i)) {
						if (json[i] === null) {
							ret.push({ text: i + ' : null', leaf: true, icon: '//static.json.cn/r/tpl/json/jsonview/jsonview/ico1/red.gif' });
						} else if (typeof json[i] === 'string') {
							ret.push({ text: i + ' : "' + json[i] + '"', leaf: true, icon: '//static.json.cn/r/tpl/json/jsonview/jsonview/ico1/blue.gif' });
						} else if (typeof json[i] === 'number') {
							ret.push({ text: i + ' : ' + json[i], leaf: true, icon: '//static.json.cn/r/tpl/json/jsonview/jsonview/ico1/green.gif' });
						} else if (typeof json[i] === 'boolean') {
							ret.push({ text: i + ' : ' + (json[i] ? 'true' : 'false'), leaf: true, icon: '//static.json.cn/r/tpl/json/jsonview/jsonview/ico1/yellow.gif' });
						} else if (typeof json[i] === 'object') {
							if (json[i] instanceof BigNumber) {
								ret.push({ text: i + ' : ' + json[i].toFixed(), leaf: true, icon: '//static.json.cn/r/tpl/json/jsonview/jsonview/ico1/green.gif' });
							} else {
								ret.push({ text: i, children: this.json2leaf(json[i]), icon: Ext.isArray(json[i]) ? '//static.json.cn/r/tpl/json/jsonview/jsonview/ico1/array.gif' : '//static.json.cn/r/tpl/json/jsonview/jsonview/ico1/object.gif' });
							}
						} else if (typeof json[i] === 'function') {
							ret.push({ text: i + ' : function', leaf: true, icon: '//static.json.cn/r/tpl/json/jsonview/jsonview/ico1/red.gif' });
						}
					}
				}
				return ret;
			},
			copyText: function () {

				if (!edit.getValue()) {
					return;
				}
				try {
					// Ext.ux.Clipboard.set(edit.getValue());
					//复制
					var clipboard = new ClipboardJS('#ext-gen22', {
						text: function (trigger) {
							if (edit.getValue()) {
								return edit.getValue();
							} else {
								return false
							}
						}
						// , success: function (e) { console.log("复制成功"); }
						// , error: function (e) { console.log("复制失败"); },
					});

					clipboard.on('success', function (e) {
						console.info('复制成功-->内容:', e.text);
						e.clearSelection();
					});

					clipboard.on('error', function (e) {
						console.info('复制失败-->内容:', e.trigger);
					});

				} catch (e) {
					//复制
					new ClipboardJS('#ext-gen28', {
						text: function (trigger) {
							if (edit.getValue()) {
								return edit.getValue();
							} else {
								return false
							}
						}
						, success: function (e) { console.log("复制成功"); }
						, error: function (e) { console.log("复制失败"); },
					});
				}
			},
			pasteText: function () {
				try {
					edit.setValue(Ext.ux.Clipboard.get());
				} catch (e) {
					alert('粘贴失败，请手动粘贴')
				}
			},
			searchStart: function () {
				if (!task) {
					task = new Ext.util.DelayedTask(this.searchFn, this);
				}
				task.delay(150);
			},
			searchFn: function () {
				searchList = [];
				if (!searchTextField.getValue()) {
					return;
				}
				this.searchInNode(root, searchTextField.getValue());
				if (searchList.length) {
					searchResultLabel.setText('');
					searchIndex = 0;
					this.selectNode(searchList[searchIndex]);
					searchTextField.focus();
				} else {
					searchResultLabel.setText('Phrase not found!');
				}
			},
			searchInNode: function (node, text) {
				if (node.text.toUpperCase().indexOf(text.toUpperCase()) !== -1) {
					searchList.push(node);
					//return true;
				}
				var isExpanded = node.isExpanded();
				node.expand(false, false);
				for (var i = 0; i < node.childNodes.length; i++) {
					if (this.searchInNode(node.childNodes[i], text)) {
						//return true;
					}
				}
				if (!isExpanded) {
					node.collapse(false, false);
				}
				//return false;
			},
			selectNode: function (node) {
				node.select();
				tree.fireEvent('click', node);
				while (node !== root) {
					node = node.parentNode;
					node.expand(false, false);
				}
			},
			searchNext: function () {
				if (!searchList || !searchList.length) {
					return;
				}
				searchIndex = (searchIndex + 1) % searchList.length;
				this.selectNode(searchList[searchIndex]);
			},
			searchPrevious: function () {
				if (!searchList || !searchList.length) {
					return;
				}
				searchIndex = (searchIndex - 1 + searchList.length) % searchList.length;
				this.selectNode(searchList[searchIndex]);
			},
			ctrlF: function () {
				if (!tree.getBottomToolbar().isVisible()) {
					tree.showBbar();
				}
				searchTextField.focus(true);
			},
			hideToolbar: function () {
				tree.hideBbar();
			},
			format: function () {
				var text = edit.getValue().split("\n").join(" ");
				var t = [];
				var tab = 0;
				var inString = false;
				for (var i = 0, len = text.length; i < len; i++) {
					var c = text.charAt(i);
					if (inString && c === inString) {
						// TODO: \\"
						if (text.charAt(i - 1) !== '\\') {
							inString = false;
						}
					} else if (!inString && (c === '"' || c === "'")) {
						inString = c;
					} else if (!inString && (c === ' ' || c === "\t")) {
						c = '';
					} else if (!inString && c === ':') {
						c += ' ';
					} else if (!inString && c === ',') {
						c += "\n" + String.space(tab * 2);
					} else if (!inString && (c === '[' || c === '{')) {
						tab++;
						c += "\n" + String.space(tab * 2);
					} else if (!inString && (c === ']' || c === '}')) {
						tab--;
						c = "\n" + String.space(tab * 2) + c;
					}
					t.push(c);
				}
				edit.setValue(t.join(''));
			},
			removeWhiteSpace: function () {
				edit.setValue(jsonviewer.getRemoveWhiteSpace());
			}
			,
			getRemoveWhiteSpace: function () {
				var text = edit.getValue().split("\n").join(" ");
				var t = [];
				var inString = false;
				for (var i = 0, len = text.length; i < len; i++) {
					var c = text.charAt(i);
					if (inString && c === inString) {
						// TODO: \\"
						if (text.charAt(i - 1) !== '\\') {
							inString = false;
						}
					} else if (!inString && (c === '"' || c === "'")) {
						inString = c;
					} else if (!inString && (c === ' ' || c === "\t")) {
						c = '';
					}
					t.push(c);
				}
				return t.join('');
			},
			removeWhiteSpace2: function () {
				var a = jsonviewer.getRemoveWhiteSpace().replace(/\"/g, "\\\"");
				edit.setValue(a);
			},
			removeZhuanyi: function () {
				var a = edit.getValue().replace(/\\\\/g, "\\").replace(/\\\"/g, '\"');
				edit.setValue(a);
			},
			expandAllTreeNode: function () {
				root.expand(true);
			},
			collapseAllTreeNode: function () {
				root.collapse(true);
			}
		};
	}();

	// 初始化 
	var temp_str = sessionStorage.getItem('temp_str');
	if (temp_str) {
		var edit = Ext.getCmp('edit');
		edit.setValue(temp_str); 
		jsonviewer.check();
	}

 
});